import ArrayUtils from "../util/ArrayUtils";
import LayaUtils from "../util/LayaUtils";
import { ADMgr } from "../wxComponent/ADManager";

/**
 * 
 * @author: xj.huang
 * @date: 2021/07/31 15:16:52
 */
class ViewMgr {
    /**界面运行脚本 */
    private runtimeMaps: Map<string, any>;
    /**正在打开中的界面 */
    private inOpenView: Map<string, any>;
    /**视图数据 */
    private viewMaps: Map<string, Laya.View | Laya.Sprite>;
    /**弹窗数据 */
    private popMaps: Map<string, Laya.View | Laya.Sprite>;
    /**打开的界面数据 */
    private openViews: Array<any>;
    private onOpenViewArr: Array<any>;
    /**加载队列数组 */
    private loadScene = [];
    /**微信顶部按钮 */
    public wxBtnPos: Laya.Point;
    /**当前视图 */
    public currentView: string;
    /**视图管理层 */
    public viewRoot: Laya.Sprite;
    /**弹窗层管理 */
    public dialog: Laya.Dialog;
    /**视图层层管理 */
    public view: Laya.View;
    /**游戏配置 */
    public gameConfig: Game.Config
    constructor() {
        this.viewMaps = new Map<string, Laya.View>();
        this.popMaps = new Map<string, Laya.Dialog>();
        this.runtimeMaps = new Map<string, any>();
        this.inOpenView = new Map<string, any>();

        this.openViews = new Array();
        this.onOpenViewArr = new Array();

    }


    private static _instance: ViewMgr;
    public static get instance(): ViewMgr {
        if (!this._instance) {
            this._instance = new ViewMgr();
        }
        return this._instance;
    }
    /**
     * 初始化界面
     * 必须执行该界面
     */
    public Init(): void {
        this.viewRoot = new Laya.Sprite();
        this.viewRoot.name = "viewRoot";
        this.viewRoot.zOrder = 99;
        Laya.stage.addChild(this.viewRoot);
        console.log("this.viewRoot", this.viewRoot)
        this.onResize()
        Laya.stage.on(Laya.Event.RESIZE, this, this.onResize)
        this.viewRoot.addChildren(this.view, this.dialog)
    }
    public addChild(node: Laya.Node) {
        this.viewRoot.addChild(node)
    }
    private onResize() {
        this.viewRoot.height = Laya.stage.height;
        this.viewRoot.width = Laya.stage.width;
        console.log("Laya.stage.height", Laya.stage.height)
    }

    /**是否全部加载完成 */
    private isLoadCompelet = true;
    /** */
    /**
     * 显示界面
     * @param url 地址
     * @param param 参数 - 可选
     * @param callBack 加载结束回调 - 可选
     */
    public async asyncOpen(url, param = {}, callBack?: Function) {
        //是否已经打开过
        let viewData = this.viewMaps.get(url);
        if (this.onOpenViewArr.length > 0) {
            this.isLoadCompelet = false;
        }
        let isOpenViewing = this.isAddOpenUrl(url, param, callBack);
        if (!viewData &&!isOpenViewing) {
            let data = await new Promise((res, rej) => {
                this.onLoadScene((view) => {
                    res(view)
                    // console.log("param",param,viewData)
                });
            })
            // console.warn("正在打开的界面", url,data,this.onOpenViewArr)
            return data;
            // this.onHideAndShowBanner()
        } else {
            if (viewData) {
                viewData['param'] = param as any;
                console.log("viewData", url)
                !viewData.parent && (this.view ? this.view : this.viewRoot)?.addChild(viewData)
            }
            // else if (popUrl) {
            //     viewUrl['param'] = param
            //     this.view.addChild(popUrl)
            // }
            return viewData //||popUrl;
            // this.onHideAndShowBanner()
        }

    }
    private isAddOpenUrl(url, param, callBack) {
        let isHasUrl = false;
        for (var k in this.onOpenViewArr) {
            if (this.onOpenViewArr[k].url === url) { isHasUrl = true; break }
        }
        if (!isHasUrl) {
            this.onOpenViewArr.push(
                {
                    callBack: callBack,
                    url: url,
                    param: param,
                }
            )
        }
        return isHasUrl
    }
    private async onLoadScene(Promise) {
        let url = this.onOpenViewArr[0].url
        let param = this.onOpenViewArr[0].param
        let callBack = this.onOpenViewArr[0].callBack
        let viewData = this.viewMaps.get(url);
        this.onOpenViewArr.splice(0, 1);
        if (!viewData) {
            viewData = await LayaUtils.asyncLoadView(url);
            if (viewData) {
                viewData['param'] = param;
                (this.view ? this.view : this.viewRoot)?.addChild(viewData)
            }
        } else {
            viewData['param'] = param;
        }
        
        this.viewMaps.set(url, viewData);
        callBack && callBack.call(window, viewData)
        Promise.call(window, viewData);
        return;

        // if (view instanceof AbstractRuntimeView) {
        //     (this.view ? this.view : this.viewRoot).addChild(view)
        // } else if (view['sceneType'] == "dialog" && view) {
        //     this.dialog.addChild(view)
        // } else {
        //     if (view instanceof Laya.View || view instanceof Laya.Scene) {
        //         (this.view ? this.view : this.viewRoot).addChild(view)
        //     } else if (view instanceof Laya.Dialog) {
        //         this.dialog.addChild(view)
        //     } else {
        //         console.error("加载" + viewdata.url + "错误", view)
        //     }
        // }
        // return viewdata;
        // console.log("this.onOpenViewArr", this.onOpenViewArr, view)

    }

    /**关闭界面 */
    public close(url) {
        let runtime = this.onGetRuntime(url)// as Laya.View;
        if (runtime && runtime.sceneType == "Laya.View") {
            runtime.destroy(true);
            runtime.removeSelf()
            this.viewMaps.delete(url)
            this.onDeleteRuntime(url)
            // console.log("关闭界面----strat", runtime, url)
            // console.log("关闭界面----end", this.view, this.viewRoot['_children'])
        } else if (runtime && runtime.sceneType == "Laya.Dialog") {
            runtime.close()
        }
    }
    /**
     * 销毁界面
     * @param url 地址
     * @param isForce 是否强制(默认：false)
     */
    public onDestroy(url: string, isForce = false) {
        let view = this.viewMaps.get(url) as any;
        if (view) {
            if (view instanceof Laya.View) {
                view.destroy(true)
                this.viewMaps.delete(url)
                this.onDeleteRuntime(url)
            }
            else if (view instanceof Laya.Dialog) {
                view.close()
                this.popMaps.delete(url)
                this.onDeleteRuntime(url)
            }
            else if (isForce && view) {
                view.destroy(true)
                this.viewMaps.delete(url)
                this.onDeleteRuntime(url)
                console.log("view", view, url)
            } else {
                console.warn("警告：" + url + " 销毁失败")
            }
            // this._onSpliceArr(url)
        }
    }

    /**设置运行脚本 */
    public onSetRuntime(url, runtime) {
        let isUrl = this.runtimeMaps.get(url)
        if (!isUrl) {
            this.runtimeMaps.set(url, runtime)
        }
    }
    /**获取界面UI运行脚本 */
    public onGetRuntime(url) {
        // console.log("this.runtimeMaps", this.runtimeMaps)
        return this.runtimeMaps.get(url)
    }
    /**移除 */
    private onDeleteRuntime(url) {
        this.runtimeMaps.delete(url)
    }
    /**异步获取UI运行脚本 */
    public async asyncGetRunTime(url) {
        return await new Promise((res, rej) => {
            let i = 0;
            Laya.timer.loop(1, this, () => {
                if (this.runtimeMaps.get(url)) {
                    res(this.runtimeMaps.get(url));
                    Laya.timer.clearAll(this);
                }
                if (i++ >= 300) {
                    Laya.timer.clearAll(this);
                    res(null)
                }
            })

        })
    }
    /**
     * 打开导出页
     * @param moreNowIndex 当前导出页索引
     * @param pageInfo 导出页信息
     */
    public async asyncExportOpen(pageInfo: Game.BoxConf, viewType = null, endCallBack?) {
        if(!Laya.Browser.onWeiXin){
            endCallBack && endCallBack.call(null, "end")
            return pageInfo
        };
        if (pageInfo.currIndex === undefined) pageInfo.currIndex = 0;
        // console.log("asyncExportOpen", pageInfo, viewType)
        if (pageInfo.currIndex == pageInfo.order.length) {
            pageInfo.currIndex = 0;
            endCallBack && endCallBack.call(null, "end")
            console.warn("所有导出页全部显示")
            return pageInfo
        } else if (pageInfo.currIndex > pageInfo.order.length) {
            console.error("所有导出页全部显示")
            return pageInfo
        }
        let url = [ViewRes.VIEW_POP, ViewRes.VIEW_FULL, ViewRes.VIEW_MENU, ViewRes.VIEW_HOT];
        let force = ["pop", "full",",menu", "hot"];
        let arrOrder = pageInfo.order
        let configPre = [
            pageInfo.is_pop,
            pageInfo.is_full,
            pageInfo.is_menu,
            pageInfo.is_hot
        ];
        let per = configPre[arrOrder[pageInfo.currIndex] - 1] ? configPre[arrOrder[pageInfo.currIndex] - 1] : 0
        let ran = Math.random() * 100;
        this.onForecExorpApp(force[arrOrder[pageInfo.currIndex] - 1]);
        console.log("ran<=configPre", ran, configPre, per, arrOrder, pageInfo.currIndex)
        if (ran <= per) {
            let openUrl = url[arrOrder[pageInfo.currIndex] - 1]
            console.log("打开知道出页",openUrl)
            await this.asyncOpen(openUrl, { viewType: viewType, pageInfo: pageInfo, endCallBack: endCallBack })
            return openUrl;
        } else {
            console.log("没有导出页",pageInfo)
            pageInfo.currIndex += 1
            return pageInfo;
        }

    }
    private onForecExorpApp(index){
        for(var k in this.gameConfig.box_conf.force){
            if(this.gameConfig.box_conf.force[k]==index){
                let wxApp;
                if(this.gameConfig.box_conf.force_id!="") {
                   wxApp= ArrayUtils.randomOne(this.gameConfig.game_box) as any
                }
                if(!wxApp){
                    wxApp = this.gameConfig.game_box[Math.floor(Math.random()*this.gameConfig.game_box.length)]
                }
                console.log("this.gameConfig.game_box",this.gameConfig.game_box,wxApp)
                wxApp &&ADMgr.openWxAPP(wxApp.app_id,wxApp.path,wxApp)
            }
        }
        
    }
}
export const UIMgr = ViewMgr.instance;